Drive Informaition
I was working with drives the other day, and wondering about the UNC (Universal Named Connection) description of my drives. I usually have several of them mapped at any one time, and was trying to display their mappings in one of my projects. A little search revealed a neat little call that is part of the more obscure Windows library of mpr.dll. The call was WNetGetConnection. I could find very little information about it anywhere - and to my amazement, it was not one that Alyce seemed to have worked out yet.
I began to do a little searching around and found more than I needed right away on the AllAPI Network. The AllAPI Network has recently moved and is hosted in its static form at: [http://www.mentalis.org/index2.shtml]

The website not only contained valuable data, but also a great example program written in Visual Basic. The VB example used a couple other more common API calls to discover the various drive data for the computer it was being run on. These are GetDriveType and GetLogicalDriveStrings. I was able to get a neatly encapsulated function for GetDriveType from Alyce's awesome API32 library - which is part of Liberty Basic Workshop. I was forced to work out my own functions for the other two calls.
Here are the API definitions courtesy of the AllAPI Network [http://www.mentalis.org/index2.shtml]:
The WNetGetConnection function retrieves the name of the network resource associated with a local device.
VB4-32,5,6
Private Declare Function WNetGetConnection Lib "mpr.dll" Alias "WNetGetConnectionA" (ByVal lpszLocalName As String, ByVal lpszRemoteName As String, cbRemoteName As Long) As Long
Operating Systems Supported
Library: Mpr
lpLocalName
(in) Pointer to a constant null-terminated string that specifies the name of the local device to get the network name for.
lpRemoteName
(out) Pointer to a buffer that receives the null-terminated remote name used to make the connection.
lpnLength
(in/out) Pointer to a variable that specifies the size, in characters, of the buffer pointed to by the lpRemoteName parameter. If the function fails because the buffer is not large enough, this parameter returns the required buffer size.
Return Values
If the function succeeds, the return value is NO_ERROR.
If the function fails, the return value is a system error code, such as one of the following values.
The GetDriveType function determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.
VB4-32,5,6
Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long
Operating Systems Supported
Library: Kernel32
lpRootPathName
Points to a null-terminated string that specifies the root directory of the disk to return information about. If lpRootPathName is NULL, the function uses the root of the current directory.
Return Values
The GetLogicalDriveStrings function fills a buffer with strings that specify valid drives in the system.
VB4-32,5,6
Declare Function GetLogicalDriveStrings Lib "kernel32" Alias "GetLogicalDriveStringsA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Operating Systems Supported
Library: Kernel32
nBufferLength
Specifies the maximum size, in characters, of the buffer pointed to by lpBuffer. This size does not include the terminating null character.
lpBuffer
Points to a buffer that receives a series of null-terminated strings, one for each valid drive in the system, that end with a second null character. The following example shows the buffer contents with [null] representing the terminating null character.
c:\[null]d:\[null][null]
Return Values
If the function succeeds, the return value is the length, in characters, of the strings copied to the buffer, not including the terminating null character. Note that an ANSI-ASCII null character uses one byte, but a Unicode null character uses two bytes.
If the buffer is not large enough, the return value is greater than nBufferLength. It is the size of the buffer required to hold the drive strings.
If the function fails, the return value is zero. To get extended error information, use the GetLastError function.
As I mentioned, one of the three API calls were in Alyce's Win32 API wrapper functions for liberty basic. It was the GetDriveType. It is presented here:
Function GetDriveType(dir$)
'print GetDriveType("c:\")
CallDLL #kernel32, "GetDriveTypeA",dir$ As Ptr,GetDriveType As Long
' dType = 0 (No Drive)
' dType = 1 (Unknown Drive Type)
' dType = 2 (Floppy Drive)
' dType = 3 (Hard Drive)
' dType = 4 (Remote Drive)
' dType = 5 (CDROM)
' dType = 6 (RAMDISK)
End Function
The key to the project however was the VB Program that was submitted to the AllAPI Network by Alexey (alexeyka2001@rambler.ru). It demonstrates all three of these API calls in use and gathers the actual UNC path of any mapped network drives. Here is the original VB program which I ported to LB
'Example by Alexey
Private Const DRIVE_UNKNOWN = 0
Private Const DRIVE_ABSENT = 1
Private Const DRIVE_REMOVABLE = 2
Private Const DRIVE_FIXED = 3
Private Const DRIVE_REMOTE = 4
Private Const DRIVE_CDROM = 5
Private Const DRIVE_RAMDISK = 6
' returns errors for UNC Path
Private Const ERROR_BAD_DEVICE = 1200&
Private Const ERROR_CONNECTION_UNAVAIL = 1201&
Private Const ERROR_EXTENDED_ERROR = 1208&
Private Const ERROR_MORE_DATA = 234
Private Const ERROR_NOT_SUPPORTED = 50&
Private Const ERROR_NO_NET_OR_BAD_PATH = 1203&
Private Const ERROR_NO_NETWORK = 1222&
Private Const ERROR_NOT_CONNECTED = 2250&
Private Const NO_ERROR = 0
Private Declare Function WNetGetConnection Lib "mpr.dll" Alias _
"WNetGetConnectionA" (ByVal lpszLocalName As String, _
ByVal lpszRemoteName As String, cbRemoteName As Long) As Long
Private Declare Function GetLogicalDriveStrings Lib "kernel32" Alias _
"GetLogicalDriveStringsA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" _
(ByVal nDrive As String) As Long
Private Function fGetDrives() As String
'Returns all mapped drives
Dim lngRet As Long
Dim strDrives As String * 255
Dim lngTmp As Long
lngTmp = Len(strDrives)
lngRet = GetLogicalDriveStrings(lngTmp, strDrives)
fGetDrives = Left(strDrives, lngRet)
End Function
Private Function fGetUNCPath(strDriveLetter As String) As String
On Local Error GoTo fGetUNCPath_Err
Dim Msg As String, lngReturn As Long
Dim lpszLocalName As String
Dim lpszRemoteName As String
Dim cbRemoteName As Long
lpszLocalName = strDriveLetter
lpszRemoteName = String$(255, Chr$(32))
cbRemoteName = Len(lpszRemoteName)
lngReturn = WNetGetConnection(lpszLocalName, lpszRemoteName, _
cbRemoteName)
Select Case lngReturn
Case ERROR_BAD_DEVICE
Msg = "Error: Bad Device"
Case ERROR_CONNECTION_UNAVAIL
Msg = "Error: Connection Un-Available"
Case ERROR_EXTENDED_ERROR
Msg = "Error: Extended Error"
Case ERROR_MORE_DATA
Msg = "Error: More Data"
Case ERROR_NOT_SUPPORTED
Msg = "Error: Feature not Supported"
Case ERROR_NO_NET_OR_BAD_PATH
Msg = "Error: No Network Available or Bad Path"
Case ERROR_NO_NETWORK
Msg = "Error: No Network Available"
Case ERROR_NOT_CONNECTED
Msg = "Error: Not Connected"
Case NO_ERROR
' all is successful...
End Select
If Len(Msg) Then
MsgBox Msg, vbInformation
Else
fGetUNCPath = Left$(lpszRemoteName, cbRemoteName)
End If
fGetUNCPath_End:
Exit Function
fGetUNCPath_Err:
MsgBox Err.Description, vbInformation
Resume fGetUNCPath_End
End Function
Private Function fDriveType(strDriveName As String) As String
Dim lngRet As Long
Dim strDrive As String
lngRet = GetDriveType(strDriveName)
Select Case lngRet
Case DRIVE_UNKNOWN 'The drive type cannot be determined.
strDrive = "Unknown Drive Type"
Case DRIVE_ABSENT 'The root directory does not exist.
strDrive = "Drive does not exist"
Case DRIVE_REMOVABLE 'The drive can be removed from the drive.
strDrive = "Removable Media"
Case DRIVE_FIXED 'The disk cannot be removed from the drive.
strDrive = "Fixed Drive"
Case DRIVE_REMOTE 'The drive is a remote (network) drive.
strDrive = "Network Drive"
Case DRIVE_CDROM 'The drive is a CD-ROM drive.
strDrive = "CD Rom"
Case DRIVE_RAMDISK 'The drive is a RAM disk.
strDrive = "Ram Disk"
End Select
fDriveType = strDrive
End Function
Sub sListAllDrives()
Dim strAllDrives As String
Dim strTmp As String
strAllDrives = fGetDrives
If strAllDrives <> "" Then
Do
strTmp = Mid$(strAllDrives, 1, InStr(strAllDrives, vbNullChar) - 1)
strAllDrives = Mid$(strAllDrives, InStr(strAllDrives, vbNullChar) + 1)
Select Case fDriveType(strTmp)
Case "Removable Media":
Debug.Print "Removable drive : " & strTmp
Case "CD Rom":
Debug.Print " CD Rom drive : " & strTmp
Case "Fixed Drive":
Debug.Print " Local drive : " & strTmp
Case "Network Drive":
Debug.Print " Network drive : " & strTmp
Debug.Print " UNC Path : " & _
fGetUNCPath(Left$(strTmp, Len(strTmp) - 1))
End Select
Loop While strAllDrives <> ""
End If
End Sub
Private Sub Form_Load()
Debug.Print "All available drives: "
sListAllDrives
End Sub
The VB Program is really quite long compared to its counterpart which I created with the help of the function definition by Alyce, and the resources show above. This program will simply enumerate the drives present on your PC. If any are connected to a network storage unit then the UNC path for that will be returned. Have fun with this one. Use it as you like. As the terms of use say: "use freely - do not claim what is not yours - give credit where credit is due - do good to all..."
Here is the program:
'port of a program to list all drives
'ported by Brad Moore
'some routines by Alyce Watson
'original by Alexey (alexeyka2001@rambler.ru)
'original author retains rights
'open source - use freely - do not claim what is not yours
' - give credit where credit is due - do good to all...
strAllDrives$ = fGetDrives$()
If strAllDrives$ <> "" Then
driveName$ = "?"
while driveName$ <> ""
index = index + 1
driveName$ = word$(strAllDrives$, index)
if len(driveName$) > 0 then
drivetype = GetDriveType(driveName$)
select case drivetype
case 0
print "Unknown Drive Type : ";driveName$
case 1
print "Absent Drive : ";driveName$
case 2
print "Removable Drive : ";driveName$
case 3
print "Fixed Logical Drive : ";driveName$
case 4
print "Network Drive : ";driveName$
'get the UNC for the drive
print "UNC Path : ";fGetUNCPath$(driveName$)
case 5
print "CD Rom Drive : ";driveName$
case 6
print "RAMDisk Drive : ";driveName$
end select
end if
wend
end if
input "Press ENTER to quit...";a$
end
'-----------------------------------------------------------------------
' the functions that support the code
Function GetDriveType(dir$)
'print GetDriveType("c:\")
CallDLL #kernel32, "GetDriveTypeA",dir$ As Ptr,GetDriveType As Long
' dType = 0 (No Drive)
' dType = 1 (Unknown Drive Type)
' dType = 2 (Floppy Drive)
' dType = 3 (Hard Drive)
' dType = 4 (Remote Drive)
' dType = 5 (CDROM)
' dType = 6 (RAMDISK)
End Function
Function fGetDrives$()
'Returns all mapped drives in a string buffer
'create a buffer of 255 characters
strDrives$ = space$(255) + chr$(0)
lngTmp = Len(strDrives$)
calldll #kernal32, "GetLogicalDriveStringsA", _
lngTmp as long, _
strDrives$ as ptr, _
result as long
fGetDrives$ = Left$(strDrives$, result)
End Function
function fGetUNCPath$(strDriveLetter$)
'returns the network UNC name for the mapped drive letter
'need a struct for the lenght argument so that it can be modified
struct RemoteNameLen, len as long
lpszLocalName$ = strDriveLetter$ + chr$(0)
'buffer to retunr the unc name
lpszRemoteName$ = space$(255) + chr$(0)
RemoteNameLen.len.struct = Len(lpszRemoteName$)
open "mpr.dll" for dll as #mpr
calldll #mpr, "WNetGetConnectionA", _
lpszLocalName as ptr, _
lpszRemoteName as ptr, _
RemoteNameLen as struct, _
result as long
close #mpr
Select Case result
Case 4608
Msg$ = "Error: Bad Device"
Case 4609
Msg$ = "Error: Connection Un-Available"
Case 4616
Msg$ = "Error: Extended Error"
Case 564
Msg$ = "Error: More Data"
Case 80
Msg$ = "Error: Feature not Supported"
Case 4611
Msg$ = "Error: No Network Available or Bad Path"
Case 4642
Msg$ = "Error: No Network Available"
Case 8784
Msg$ = "Error: Not Connected"
Case 0
remoteLen = RemoteNameLen.len.struct
Msg$ = Left$(lpszRemoteName, remoteLen)
Case else
Msg$ = "Unknown condition on return: " + str$(result)
End Select
fGetUNCPath$ = Msg$
'returns errors for UNC Path explained:
'ERROR_BAD_DEVICE = 4608
'ERROR_CONNECTION_UNAVAIL = 4609
'ERROR_EXTENDED_ERROR = 4616
'ERROR_MORE_DATA = 564
'ERROR_NOT_SUPPORTED = 80
'ERROR_NO_NET_OR_BAD_PATH = 4611
'ERROR_NO_NETWORK = 4642
'ERROR_NOT_CONNECTED = 8784
'NO_ERROR = 0
end function